//============================================================================
// Name             : CSE325Project1.cpp
// Author           : Ahbiya Harris ; Alyza Villa
// Effort Division  : 50/50
// Copyright        : CSE325-12456 Embedded Microprocessor Systems
//				      Lab Project 1
//				      Spring 2013
// Description      : Bit manipulations function.
//============================================================================


#include "BitFunctions.h"

/*
* Sets the bit at position position in CF_LONGWord number.
*/
void setBit(CF_LONGWord& number, int position)
{
	CF_LONGWord tempWord = (((CF_LONGWord) 1) << position);
	number |= tempWord;
}

/*
* Sets the bit at position position in CF_LONGWord number to Boolean value
* value.
*/
void setBit(CF_LONGWord& number, int position, bool value)
{
	CF_LONGWord tempWord = (((CF_LONGWord) 1) << position);

	if (value)
		number |= tempWord;
	else
	{
		tempWord = ~tempWord;
		number &= tempWord;
	}
}

/*
* Clears the bit at position position in CF_LONGWord number.
*/
void clearBit(CF_LONGWord& number, int position)
{
	setBit(number, position, 0);
}

/*
* Sets the bits from highPosition to lowPosition in integer number to value value.
*/
void setBits(CF_LONGWord &number, int highPosition, int lowPosition, CF_LONGWord value)
{
	for(int index=0, jIndex=lowPosition; jIndex<highPosition+1; index++, jIndex++)
		setBit(number, jIndex, getBit( (value >> index), 0));
}

/*
* Returns the value of the bit at position position in CF_LONGWord number.
*/
bool getBit(CF_LONGWord number, int position)
{
	return (CF_LONGWord) ((number >> position) & 1);
}

/*
* Returns the value of bits from highPosition to lowPosition in CF_LONGWord number.
*/
CF_LONGWord getBits(CF_LONGWord number, int highPosition, int lowPosition)
{
	if (highPosition == lowPosition)
		return getBit(number, highPosition);

	if (highPosition < lowPosition)
		return getBits(number, lowPosition, highPosition);

	CF_LONGWord temp = number << (31 - highPosition);
	temp >>= 31 - highPosition + lowPosition;
	return temp;
}

/*
* Returns the byte at position position in number number
*/
CF_Byte getByte(CF_LONGWord number, int position)
{
	return (CF_Byte) getBits(number, (position<<3)+7, (position<<3));
}

/*
* Sets the byte at position position in number number to value value.
*/
void setByte(CF_LONGWord& number, int position, CF_Byte value)
{
	setBits(number, (position<<3)+7, (position<<3), value);
}

/*
* Returns the word at position position in number number in a LittleEndian Machine.
*/
CF_Word getWordLittleEndian(CF_LONGWord number, int position)
{
	return (CF_Word) getBits(number, (position<<4)+15, (position<<4));
}

/*
* Returns the word at position position in number number in a BigEndian Machine.
*/
CF_Word getWordBigEndian(CF_LONGWord number, int position)
{
	CF_Word tempWord = (CF_Word) getBits(number, (position<<4)+15, (position<<4));
	return ((tempWord&0xff)<<24)+((tempWord&0xff00)<<8)+((tempWord&0xff0000)>>8)+((tempWord>>24)&0xff);
}

/*
* Sets the word at position position in number number to value value.
*/
void setWord(CF_LONGWord& number, int position, CF_Word value)
{
	setBits(number, (position<<4)+15, (position<<4), value);
}
